package com.ark.frigate.dingtalk.ding;

import java.util.Arrays;
import java.util.stream.Collectors;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;

import com.ark.frigate.dingtalk.ding.message.MarkDownMessage;
import com.ark.frigate.dingtalk.utils.EnvironmentUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 异常报警
 * <p>
 * https://developers.dingtalk.com/document/app/custom-robot-access
 *
 * @author zengweilong
 */
@Slf4j
public class DingTalkMarkdownMessage extends DingTalkMessage {

    public void sendTextEx(Throwable e, String title) {
        sendCoreExMessage(StringUtils.EMPTY, StringUtils.EMPTY, e, title, ArrayUtils.EMPTY_STRING_ARRAY);
    }

    public void sendTextExMsg(Throwable e, String title) {
        sendCoreExMessage(StringUtils.EMPTY, StringUtils.EMPTY, e, title, ArrayUtils.EMPTY_STRING_ARRAY);
    }

    public void sendTextEx(String dingTalkUrl, String secret, String title, Throwable e) {
        sendCoreExMessage(dingTalkUrl, secret, e, title, ArrayUtils.EMPTY_STRING_ARRAY);
    }

    public void sendTextEx(Throwable e, String title, String[] phones) {
        sendCoreExMessage(StringUtils.EMPTY, StringUtils.EMPTY, e, title, phones);
    }

    public void sendTextMsg(String dingTalkUrl, String secret, Throwable e, String title) {
        sendCoreExMessage(dingTalkUrl, secret, e, title, ArrayUtils.EMPTY_STRING_ARRAY);
    }

    public void sendText(String title, String content) {
        sendCoreTextMessage(StringUtils.EMPTY, StringUtils.EMPTY, title, content, ArrayUtils.EMPTY_STRING_ARRAY);
    }

    public void sendText(String dingTalkUrl, String secret, String title, String content) {
        sendCoreTextMessage(dingTalkUrl, secret, title, content, ArrayUtils.EMPTY_STRING_ARRAY);
    }

    /**
     * 发送带异常栈的钉钉消息
     *
     * @param dingTalkUrl
     * @param e
     * @param atMobiles
     */
    public void sendCoreExMessage(String dingTalkUrl, String secret, Throwable e, String title, String[] atMobiles) {
        StringBuilder content = getHead(title, atMobiles);
        getExtInfo(e, content).append(StringUtils.LF);
        //getExtCase(e, content).append(StringUtils.LF);
        //getExtStack(e, content).append(StringUtils.LF);
        sendCoreMarkDown(dingTalkUrl, secret, title, content.toString(), atMobiles);
    }

    /**
     * 发送其他
     *
     * @param dingTalkUrl
     * @param secret
     * @param title
     * @param content
     * @param atMobiles
     */
    public void sendCoreTextMessage(String dingTalkUrl, String secret, String title, String content,
                                    String[] atMobiles) {
        //content = getHead(title, atMobiles).append(">").append(content).toString();
        sendCoreMarkDown(dingTalkUrl, secret, title, content, atMobiles);
    }

    /**
     * 发送文本消息
     *
     * @param dingTalkUrl
     * @param title
     * @param content
     * @param atMobiles
     */
    private void sendCoreMarkDown(String dingTalkUrl, String secret, String title, String content,
                                  String[] atMobiles) {
        content = StringUtils.substring(content, 0, 16000);
        MarkDownMessage markDownMessage = new MarkDownMessage();
        markDownMessage.setDingTalkUrl(dingTalkUrl);
        markDownMessage.setSecret(secret);
        markDownMessage.setMarkDown(title, content);

        if (ArrayUtils.isEmpty(atMobiles)) {
            atMobiles = StringUtils.split(dingTalkConfig.getPhones(), ",");
        }

        markDownMessage.setAtMobiles(atMobiles);
        try {
            sendCoreMessage(markDownMessage);
        } catch (Exception ex) {
            log.error("钉消息发送失败={}", markDownMessage, ex);
        }
    }

    private StringBuilder getHead(String title, String[] atMobiles) {
        StringBuilder text = new StringBuilder();
        text.append("<font color=\"#dd0000\">【发生异常】</font>").append(StringUtils.LF);
        text.append("#### **异常主题 :** ").append(title).append(StringUtils.LF);
        text.append("#### **所属环境 :** ").append(getEnv()).append(StringUtils.LF);
        text.append("#### **主机名称 :** ").append(EnvironmentUtil.getHostName()).append(StringUtils.LF);
        text.append("#### **主机地址 :** ").append(EnvironmentUtil.getHostIp()).append(StringUtils.LF);
        String requestId = MDC.get("requestId");
        if (StringUtils.isNotBlank(requestId)) {
            text.append("#### **日志追踪 :** ").append(requestId).append(StringUtils.LF);
        }
        if (ArrayUtils.isNotEmpty(atMobiles)) {
            String collect = Arrays.stream(atMobiles).map(m -> "@" + m).collect(Collectors.joining(","));
            text.append("#### **关注人 :** ").append(collect).append(StringUtils.LF);
        }
        return text;
    }

    private StringBuilder getExtInfo(Throwable e, StringBuilder content) {
        content.append("#### **异常信息 :** ").append(StringUtils.LF);
        content.append(">").append(e).append(StringUtils.LF).append(StringUtils.LF);
        return content;
    }

    /**
     * Throwable 解析
     *
     * @param e
     * @param content
     *
     * @return
     */
    private StringBuilder getExtStack(Throwable e, StringBuilder content) {
        content.append("#### **异常栈 :** ").append(StringUtils.LF);
        content.append(">");
        StackTraceElement[] elements = e.getStackTrace();
        if (ArrayUtils.isEmpty(elements)) {
            return content;
        }
        for (StackTraceElement element : elements) {
            content.append(element).append(StringUtils.LF);
        }
        return content;
    }

    /**
     * Throwable 解析
     *
     * @param e
     * @param content
     *
     * @return
     */
    private StringBuilder getExtCase(Throwable e, StringBuilder content) {
        content.append("#### **异常Cause :** ").append(StringUtils.LF);
        if (e.getCause() == null) {
            content.append(e).append(StringUtils.LF);
            return content;
        }
        content.append(e.getCause()).append(StringUtils.LF);

        content.append(">");
        StackTraceElement[] elements = e.getCause().getStackTrace();
        if (ArrayUtils.isEmpty(elements)) {
            return content.append(e);
        }
        for (StackTraceElement element : elements) {
            if (element.toString().contains(dingTalkConfig.getPackageName())) {
                content.append(element).append(StringUtils.LF);
            }
        }
        return content;
    }

}
